import { Component, director, Node, Scene } from "cc";
import { Logger } from "../../common/log/Logger";
import { EventDispatcher } from "../../event";
import { injectable } from "../../inject";
import { Command } from "../../mvcs/Command";
import { View_Name_Tag } from "../../mvcs/impl/ViewMap";

@injectable('SwitchViewCommand')
export class SwitchViewCommand extends Command {
    public async execute(viewName: string, payload: any): Promise<void> {
        let view: Node = await this.injector.getInstance(viewName);

        let sceneMediator = this.injector.getValue('CurrentSceneMediator');
        let dispatcher: EventDispatcher = this.dispatcher;

        let comp = view.addComponent(Component);
        comp['onLoad'] = () => {
            dispatcher.emit('Evt_Added_To_Stage', view);
        }

        comp['onDestroy'] = () => {
            dispatcher.emit('Evt_Removed_From_State', view);
        }

        sceneMediator.switchView(view);
    }
}

@injectable('PushViewCommand')
export class PushViewCommand extends Command {
    public async execute(viewName: string, payload: any): Promise<void> {
        let view: Node = await this.injector.getInstance(viewName);

        let sceneMediator = this.injector.getValue('CurrentSceneMediator');
        let dispatcher: EventDispatcher = this.dispatcher;

        let comp = view.addComponent(Component);
        comp['onLoad'] = () => {
            dispatcher.emit('Evt_Added_To_Stage', view);
        }

        comp['onDestroy'] = () => {
            dispatcher.emit('Evt_Removed_From_State', view);
        }

        sceneMediator.pushView(view);
    }
}

@injectable('PopupViewCommand')
export class PopupViewCommand extends Command {
    public execute(...args: any[]): void {
        throw new Error("Method not implemented.");
    }
}

@injectable('ShowToastCommand')
export class ShowToastCommand extends Command {
    public execute(...args: any[]): void {
        throw new Error("Method not implemented.");
    }
}

@injectable('SwitchSceneCommand')
export class SwitchSceneCommand extends Command {
    public execute(sceneName: string, options: any): void {
        Logger.debug('SwitchSceneCommand execute');

        let mediatorMap = this.mediatorMap;

        let curSceneMediator = this.injector.getValue('CurrentSceneMediator')
        if (curSceneMediator)
            mediatorMap.removeMediator(curSceneMediator);

        let sceneaaName: string = this.injector.getInstance(sceneName);
        director.loadScene(sceneaaName, (err, newScene: Scene) => {

            Object.defineProperty(newScene, View_Name_Tag, {
                value: sceneName,
                writable: false,
                configurable: false,
                enumerable: false
            })

            mediatorMap.createMediator(newScene);
        })

        // let newScene: Scene = this.injector.getInstance('login_scene_creator');
        // let mediator = this.mediatorMap.createMediator(newScene);
        // if (mediator) {
        //     let comp = newScene.addComponent(Component);
        //     comp['onLoad'] = () => {
        //         mediatorMap.registerMediator(newScene, mediator);
        //     }

        //     comp['onDestroy'] = () => {
        //         mediatorMap.removeMediatorByView(newScene);
        //     }
        // }



        // director.runScene(newScene);
    }

}